<?php

namespace api\quant\controller;

use cmf\controller\RestBaseController;
use think\Db;
use think\Validate;

class RobotController extends RestBaseController
{
    //可用的market list
    public function marketList()
    {
        $platforms = implode(',', Db::name("third_platform")->column('platform'));
        $validate = new Validate([
            'platform'     => 'require|in:' . $platforms,
            'type'     => 'require|in:spot',
        ]);

        $validate->message([
            'platform.require'  => '平台不能为空!',
            'type.require'  => '市场类型不能为空!',
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }
        $platform = $data['platform'];
        $where = array();
        $where['platform'] = $platform;
        $where['status'] = 1;
        $marketList = Db::name("spot_market")->where($where)->select();
        if ($marketList) {
            $marketList =  $marketList->toArray();
        }
        $this->success('success', $marketList);
    }

    /*
* post 发送JSON 格式数据
* @param $url string URL
* @param $data_string string 请求的具体内容
* @return array
* code 状态码
* result 返回结果
*/
    function post_json_data($url, $data_string) {
//初始化
        $ch = curl_init();
//设置post方式提交
        curl_setopt($ch, CURLOPT_POST, 1);
//设置抓取的url
        curl_setopt($ch, CURLOPT_URL, $url);
//设置post数据
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
//设置头文件的信息作为数据流输出
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json; charset=utf-8',
                'Content-Length: ' . strlen($data_string))
        );
        ob_start();
//执行命令
        curl_exec($ch);
        $return_content = ob_get_contents();
        ob_end_clean();
        $return_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        return array('code'=>$return_code, 'result'=>$return_content);
    }

    //机器人列表
//    {"first_order_price": 0.14775, "base_price": 0.14775, "up_price": 0, "down_price": 0, "trend_side": 0, "order_count": 1, "deal_amount": 66.933, "deal_money": 9.89925, "order_finish": 0, "pid": "e6033019-3008-410c-98b3-c7a38eb09c3b", "deal_fee": 0.067}
    public function robotList()
    {
        $userId = $this->getUserId();
        //机器人列表
        $where = array();
        $where['uid'] = $userId;
        $fieldStr = 'a.*,b.market_name,b.stock,b.money';
        $robot_list = Db::name("quant_robot")
            ->alias('a')
            ->join(config('database.prefix') . 'spot_market b', "a.market_id = b.id", "LEFT")
            ->field($fieldStr)
            ->where($where)
            ->order('a.id desc')
            ->select();
        if ($robot_list) {
            $robot_list = $robot_list->toArray();
        }
        foreach ($robot_list as &$robot) {
            //unset($robot['values_str']);
            $robot['cover_str'] =  $cover_str = json_decode($robot['cover_str'],1);
            if($robot['is_fxkz'] == 1){
                $robot['is_fxkz'] = true;
            }else{
                $robot['is_fxkz'] = false;
            }
            if($robot['values_str']){
                $values_str = json_decode($robot['values_str'],1);
                //持仓均价
                $average_price = $values_str['deal_money']/$values_str['deal_amount'];
                //止盈比例
                $stop_profit_rate = $robot['stop_profit_rate'];
                //预估止盈
                $yj_stop_number = $average_price + ($average_price * $stop_profit_rate /100);
                $robot['yj_stop_number'] = round($yj_stop_number,5);

                //获取盈亏=当前价格-持仓均价
//                调用其他控制器
                $info['exchange'] = $robot['platform'];
                $info['market'] = $robot['market_name'];
                $info['currency'] = 'USD';

                $url = $this->request->domain();

                $result=$this->post_json_data($url.'/api/trade/public/ticker',json_encode($info));
                if($result){
                    $result = json_decode($result['result'],true);
                    $robot['revenue'] = ($result['data']['last'] - $average_price) * $values_str['deal_amount'];
                }else{
                    $robot['revenue'] = 0;
                }

//                dump(json_decode($result['result'],true));die;
            }else{
                $robot['yj_stop_number'] = 0;
                $robot['revenue'] = 0;
            }

            if($cover_str){
                $all = 0;
                foreach ($cover_str as $k=>$v){
                    $all += $v['cover_multiple'];
                }
                $robot['cover_bs'] = $all;
            }else{
                $robot['cover_bs'] = 0;
            }

        }
        $this->success('success', $robot_list);
    }

    //创建机一个机器人
    public function create()
    {
        $userId = $this->getUserId();
        $platforms = implode(',', Db::name("third_platform")->column('platform'));
        $validate = new Validate([
            'platform'     => 'require|in:' . $platforms,
            'market_id' => 'require|gt:0',
            'first_order_value' => 'require|number|gt:0',
            'stop_profit_rate' => 'require|number|gt:0',
            'max_order_count' => 'number',
            'cover_num' => 'number',
            'stop_profit_callback_rate' => 'require|number|gt:0',
            'cover_callback_rate' => 'require|number|gt:0',
            'recycle_status' => 'require|integer|in:0,1',
        ]);

        $validate->message([
            'platform.require'  => '平台不能为空!',
            'max_order_count.number' =>'做单数量必须是数字',
            'cover_num.number' =>'补仓次数必须是数字'
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }
        if(!$data['max_order_count'] && !$data['cover_num']){
            $this->error("请设置做单次数或者补仓次数");
        }
        //check api
        $platform = $data['platform'];
        $where = array();
        $where['platform'] = $platform;
        $where['uid'] = $userId;
        $where['status'] = 1;
        $findApi = Db::name("third_api")->where($where)->count();
        if ($findApi < 1) {
            $this->error("当前无可用的API，请先绑定:" . $platform);
        }
        //check market_id
        $market_id = $data['market_id'];
        $where = array();
        $where['platform'] = $platform;
        $where['id'] = $market_id;
        $where['status'] = 1;
        $findMarket = Db::name("spot_market")->where($where)->count();
        if ($findMarket < 1) {
            $this->error("指定的市场ID不可用:" . $market_id);
        }
        $where = array();
        $where['uid'] = $userId;
        $where['market_id'] = $market_id;
        $findRobot =  Db::name("quant_robot")->where($where)->count();
        if ($findRobot > 0) {
            $this->error("你已经创建该平台交易区的机器人了:" . $market_id);
        }
        //check cd key
        $app_conf = cmf_get_option('app_config');
        $cdkey_price = floatval($app_conf['cdkey_price']);
        $need_cdkey = 0;
        //检测用户是不是VIP套餐有效期内
        $vip_deadline =  Db::name("user")->where('id', $userId)->value('vip_deadline');
        if ($vip_deadline < time()) { //不是VIP 检测激活码需不需要
            if ($cdkey_price > 0) { //cdkey 启用了
                $need_cdkey = 1;
                if (!isset($data['cd_key']) || empty($data['cd_key'])) {
                    $this->error("请输入激活码创建机器人");
                }
                $cd_key = $data['cd_key'];
                $where = array();
                $where['keys'] = $cd_key;
                $where['uid'] = $userId;
                $where['used'] = 0;
                $findKey = Db::name("cdkey_logs")->where($where)->find();
                if (empty($findKey)) {
                    $this->error("cdkey不存在或者已经失效:" . $cd_key);
                }
            }
        }

        Db::startTrans();
        //创建机器人
        $data['uid'] = $userId;
        $data['status'] = 0;
        $data['type'] = 1; //1 spot
        if($data['is_fxkz'] == 'true'){
            $data['is_fxkz'] = 1;
        }else{
            $data['is_fxkz'] = 0;
        }
        if($data['cover_str']){
            $data['cover_str'] = json_encode($data['cover_str']);
        }
        $field = 'uid,status,type,cd_key,platform,market_id,first_order_value,max_order_count,stop_profit_rate, stop_profit_callback_rate, cover_rate, cover_callback_rate, recycle_status,cover_number,stop_number,max_loop_num,is_fxkz,buy_min,buy_max,cover_str,cover_num';
        $ret = Db::name("quant_robot")->field($field)->insertGetId($data);
        if ($ret) {
            //标记cd_key
            if ($need_cdkey) {
                $ret2 = Db::name("cdkey_logs")->where('id', $findKey['id'])->update(array('used' => 1, 'qrobot_id' => $ret));
            } else {
                $ret2 = 1;
            }
            if ($ret2) {
                Db::commit();
                $this->success('创建成功');
            } else {
                Db::rollback();
                $this->error('创建失败，请稍后再试#2');
            }
        } else {
            Db::rollback();
            $this->error('创建失败，请稍后再试#1');
        }
    }

    //创建机一个机器人
    public function edit()
    {
        $userId = $this->getUserId();
        $validate = new Validate([
            'robot_id' => 'require|integer|gt:0',
            'first_order_value' => 'number|gt:0',
            'stop_profit_rate' => 'number|gt:0',
            'stop_profit_callback_rate' => 'number|gt:0',
            'max_order_count' => 'number',
            'cover_num' => 'number',
            'cover_callback_rate' => 'number|gt:0',
            'recycle_status' => 'integer|in:0,1',
        ]);
        $validate->message([
            'robot_id.require'  => 'robot_id不能为空!',
            'max_order_count.number' =>'做单数量必须是数字',
            'cover_num.number' =>'补仓次数必须是数字'
        ]);
        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }
        if(!$data['max_order_count'] && !$data['cover_num']){
            $this->error("请设置做单次数或者补仓次数");
        }
        //check robot
        $where = array();
        $where['uid'] = $userId;
        $where['id'] = $data['robot_id'];
        $findRobot = Db::name("quant_robot")->where($where)->find();
        if (empty($findRobot)) {
            $this->error("你无权访问该机器人");
        }
        if($data['is_fxkz'] == 'true'){
            $data['is_fxkz'] = 1;
        }else{
            $data['is_fxkz'] = 0;
        }
        if($data['cover_str']){
            $data['cover_str'] = json_encode($data['cover_str']);
        }
        $field = 'first_order_value,max_order_count,stop_profit_rate, stop_profit_callback_rate, cover_rate, cover_callback_rate, recycle_status,cover_number,stop_number,max_loop_num,is_fxkz,buy_min,buy_max,cover_str,cover_num';
        $ret = Db::name("quant_robot")
            ->where('id', $findRobot['id'])
            ->field($field)
            ->update($data);
        if ($ret !== false) {
            $this->success('更改成功');
        } else {
            $this->error('更改失败');
        }
    }
    //禁用机器人
    public function disable()
    {

        $userId = $this->getUserId();

        $validate = new Validate([
            'robot_id' => 'require|integer|gt:0',

        ]);

        $validate->message([
            'robot_id.require'  => 'robot_id不能为空!',
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }
        //check robot
        $where = array();
        $where['uid'] = $userId;
        $where['id'] = $data['robot_id'];
        $findRobot = Db::name("quant_robot")->where($where)->find();
        if (empty($findRobot)) {
            $this->error("你无权访问该机器人");
        }
        //清仓未成功之前不能禁用
        if($findRobot && $findRobot['is_clean'] == 1){
            $this->error("清仓卖出中不能禁用");
        }
        $update_data = array('status' => 0,'is_gua'=>0);
        $ret = Db::name("quant_robot")->where('id', $findRobot['id'])->update($update_data);
        if ($ret !== false) {
            $this->success('禁用成功');
        } else {
            $this->error('禁用失败');
        }
    }

    //清仓卖出
    public function clean()
    {

        $userId = $this->getUserId();

        $validate = new Validate([
            'robot_id' => 'require|integer|gt:0',

        ]);

        $validate->message([
            'robot_id.require'  => 'robot_id不能为空!',
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->success($validate->getError());
        }
        //check robot
        $where = array();
        $where['uid'] = $userId;
        $where['id'] = $data['robot_id'];
        $findRobot = Db::name("quant_robot")->where($where)->find();
        if (empty($findRobot)) {
            $this->success("你无权访问该机器人");
        }
        if ($findRobot['status'] == 0) {
            $this->success("机器人未启动,无法清仓");
        }
        $update_data = array('is_clean' => 1,'is_gua'=>0);
        $ret = Db::name("quant_robot")->where('id', $findRobot['id'])->update($update_data);
        if ($ret !== false) {
            $this->success('清仓成功,即将执行');
        } else {
            $this->error('清仓失败');
        }
    }

    //清仓卖出
    public function orderClean()
    {

        $userId = $this->getUserId();

        $validate = new Validate([
            'order_id' => 'require|integer|gt:0',

        ]);

        $validate->message([
            'order_id.require'  => 'order_id不能为空!',
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->success($validate->getError());
        }
        //check robot
        $where = array();
        $where['uid'] = $userId;
        $where['id'] = $data['order_id'];
        $findRobot = Db::name("quant_robot_order")->where($where)->find();
        if (empty($findRobot)) {
            $this->success("你无权操作该订单");
        }

        if ($findRobot['clean_status'] == 1) {
            $this->success("已经清仓完成");
        }
        if ($findRobot['is_clean'] == 1) {
            $this->success("清仓执行中");
        }
        $update_data = array('is_clean' => 1);
        $ret = Db::name("quant_robot_order")->where('id', $findRobot['id'])->update($update_data);
        if ($ret !== false) {
            $this->success('清仓成功,即将执行');
        } else {
            $this->error('清仓失败');
        }
    }

    //一键补仓
    public function cover()
    {

        $userId = $this->getUserId();

        $validate = new Validate([
            'robot_id' => 'require|integer|gt:0',

        ]);

        $validate->message([
            'robot_id.require'  => 'robot_id不能为空!',
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->success($validate->getError());
        }
        //check robot
        $where = array();
        $where['uid'] = $userId;
        $where['id'] = $data['robot_id'];
        $findRobot = Db::name("quant_robot")->where($where)->find();
        if (empty($findRobot)) {
            $this->success("你无权访问该机器人");
        }
        if ($findRobot['status'] == 0) {
            $this->success("机器人未启动,无法补仓");
        }
        $update_data['is_gua'] = $data['is_gua'];
        $update_data['gua_price'] = $data['gua_price']??0;
        $update_data['gua_num'] = $data['gua_num']??0;
        $ret = Db::name("quant_robot")->where('id', $findRobot['id'])->update($update_data);
        if ($ret !== false) {
            $this->success('设置成功,即将执行');
        } else {
            $this->error('设置失败');
        }
    }

    //启用机器人
    public function enable()
    {

        $userId = $this->getUserId();

        $validate = new Validate([
            'robot_id' => 'require|integer|gt:0',

        ]);

        $validate->message([
            'robot_id.require'  => 'robot_id不能为空!',
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }
        //check robot
        $where = array();
        $where['uid'] = $userId;
        $where['id'] = $data['robot_id'];
        $findRobot = Db::name("quant_robot")->where($where)->find();
        if (empty($findRobot)) {
            $this->error("你无权访问该机器人");
        }

        $app_conf = cmf_get_option("app_config");
        if (!isset($app_conf['quant_revenue_type'])) { //|| empty($app_conf['quant_revenue_type']
            $this->error("系统未设置计费方式");
        }
        if (!isset($app_conf['quant_startup_min'])) {
            $this->error("系统未设置启动门槛");
        }
        $quant_revenue_type = intval($app_conf['quant_revenue_type']);
        $amount = floatval($app_conf['quant_startup_min']);

        if ($quant_revenue_type == 1) {
            //check usdt balance 
            $coin_symbol = 'USDT';
            //查询用户对应币种余额
            $cloud_wallet = Db::name("Wallet")->where(['uid' => $userId, 'coin_symbol' => $coin_symbol, 'type' => 1])->field('id,coin_symbol,cloud_balance,address')->find();
            if (empty($cloud_wallet)) {
                $this->error("查询不到云端钱包账户信息，请稍后重试");
            }
            $cloud_balance = $cloud_wallet['cloud_balance'];
            if ($amount > $cloud_balance) {
                $this->error("启动机器人需要满足：{$coin_symbol}钱包余额大于" . $amount);
            }
        } else {
            $user_balance = Db::name("user")->where(['id' => $userId])->value('balance');
            if ($amount > $user_balance) {
                $this->error("启动机器人需要满足：燃料余额大于" . $amount);
            }
        }
        //check api
        $platform = $findRobot['platform'];
        $where = array();
        $where['platform'] = $platform;
        $where['uid'] = $userId;
        $where['status'] = 1;
        $findApi = Db::name("third_api")->where($where)->count();
        if ($findApi < 1) {
            $this->error("当前无可用的API，请先绑定:" . $platform);
        }
        //check market_id
        $market_id = $findRobot['market_id'];
        $where = array();
        $where['platform'] = $platform;
        $where['id'] = $market_id;
        $where['status'] = 1;
        $findMarket = Db::name("spot_market")->where($where)->count();
        if ($findMarket < 1) {
            $this->error("指定的市场ID不可用:" . $market_id);
        }
        $where = array();
        $where['uid'] = $userId;
        $where['market_id'] = $market_id;
        $where['status'] = 1;
        $count =  Db::name("quant_robot")->where($where)->count();
        if ($count > 0) {
            $this->error("你已经创建该平台交易区的机器人了:" . $market_id);
        }
        $update_data = array('status' => 1,'now_cover_num'=>0,'loop_num'=>0);
        $ret = Db::name("quant_robot")->where('id', $findRobot['id'])->update($update_data);
        if ($ret !== false) {
            $this->success('启用成功');
        } else {
            $this->error('启用失败');
        }
    }
    //日志
    public function log()
    {
        $userId = $this->getUserId();

        $validate = new Validate([
            'robot_id' => 'integer|gt:0',
            'limit_begin'    => 'integer',
            'limit_end'     => 'integer'
        ]);

        $validate->message([
            //'robot_id.require'  => 'robot_id不能为空!',
            'limit_begin.integer'  => 'limit_begin必须为整数!',
            'limit_end.integer'  => 'limit_end必须为整数!'
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }
        if (!empty($data['limit_begin'])) {
            $limit_begin = $data['limit_begin'];
        } else {
            $limit_begin = 0;
        }

        if (!empty($data['limit_end'])) {
            $limit_end = $data['limit_end'];
        } else {
            $limit_end = 10;
        }
        //check robot
        $where = array();
        $where['uid'] = $userId;
        if (isset($data['robot_id'])) {
            $where['id'] = $data['robot_id'];
        }
        $findRobot = Db::name("quant_robot")->where($where)->find();
        if (empty($findRobot)) {
            $this->error("你无权访问该机器人");
        }

        $where = array();
        $where['uid'] = $userId;
        if (isset($data['robot_id'])) {
            $where['qrobot_id'] = $data['robot_id'];
        }
        $log_list =  Db::name("quant_robot_log")
            ->where($where)
            ->order('id desc')
            ->limit($limit_begin, $limit_end)
            ->select();

        $total_count =  Db::name("quant_robot_log")
            ->where($where)
            ->order('id desc')
            ->count();

        $return_data['data'] = $log_list;
        $return_data['total_count'] = $total_count;
        $this->success('success', $return_data);
    }
    //机器人订单
    public function order()
    {
        $userId = $this->getUserId();

        $validate = new Validate([
            'robot_id' => 'integer|gt:0',
            'limit_begin'    => 'integer',
            'limit_end'     => 'integer'
        ]);

        $validate->message([
            //'robot_id.require'  => 'robot_id不能为空!',
            'limit_begin.integer'  => 'limit_begin必须为整数!',
            'limit_end.integer'  => 'limit_end必须为整数!'
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }
        if (!empty($data['limit_begin'])) {
            $limit_begin = $data['limit_begin'];
        } else {
            $limit_begin = 0;
        }

        if (!empty($data['limit_end'])) {
            $limit_end = $data['limit_end'];
        } else {
            $limit_end = 10;
        }
        //check robot
        $where = array();
        $where['uid'] = $userId;
        if (isset($data['robot_id'])) {
            $where['id'] = $data['robot_id'];
        }
        $findRobot = Db::name("quant_robot")->where($where)->find();
        if (empty($findRobot)) {
            $this->error("你无权访问该机器人");
        }

        $where = array();
        if (isset($data['robot_id'])) {
            $where['qrobot_id'] = $data['robot_id'];
        }
        $where['uid'] = $userId;
        $order_list =  Db::name("quant_robot_order")
            ->where($where)
            ->order('id desc')
            ->limit($limit_begin, $limit_end)
            ->select();

        $total_count =  Db::name("quant_robot_order")
            ->where($where)
            ->order('id desc')
            ->count();

        $return_data['data'] = $order_list;
        $return_data['total_count'] = $total_count;
        $this->success('success', $return_data);
    }

    //机器人收益
    public function revenue()
    {
        $userId = $this->getUserId();

        $validate = new Validate([
            'robot_id' => 'integer|gt:0',
            'limit_begin'    => 'integer',
            'limit_end'     => 'integer'
        ]);

        $validate->message([
            //'robot_id.require'  => 'robot_id不能为空!',
            'limit_begin.integer'  => 'limit_begin必须为整数!',
            'limit_end.integer'  => 'limit_end必须为整数!'
        ]);

        $data = $this->request->param();
        if (!$validate->check($data)) {
            $this->error($validate->getError());
        }
        if (!empty($data['limit_begin'])) {
            $limit_begin = $data['limit_begin'];
        } else {
            $limit_begin = 0;
        }

        if (!empty($data['limit_end'])) {
            $limit_end = $data['limit_end'];
        } else {
            $limit_end = 10;
        }
        //check robot
        $where = array();
        $where['uid'] = $userId;
        if (isset($data['robot_id'])) {
            $where['id'] = $data['robot_id'];
        }
        $findRobot = Db::name("quant_robot")->where($where)->find();
        if (empty($findRobot)) {
            //$this->error("你无权访问该机器人");
            $return_data['data'] = array();
            $return_data['total_count'] = 0;
            $return_data['total_revenue'] = 0;
            $return_data['today_revenue'] = 0;
            $this->success('success', $return_data);            
        }

        $where = array();
        if (isset($data['robot_id'])) {
            $where['qrobot_id'] = $data['robot_id'];
        }
        $where['uid'] = $userId;
        $revenue_list =  Db::name("quant_robot_revenue")
            ->where($where)
            ->order('id desc')
            ->limit($limit_begin, $limit_end)
            ->select();

        $total_count =  Db::name("quant_robot_revenue")
            ->where($where)
            ->order('id desc')
            ->count();

        $total_revenue =  Db::name("quant_robot_revenue")
            ->where($where)
            ->order('id desc')
            ->sum('revenue');
        $today = date("Y-m-d H:i:s", strtotime(date('Y-m-d')));

        $today_revenue =  Db::name("quant_robot_revenue")
            ->where($where)
            ->where("ctime > '{$today}'")
            ->order('id desc')
            ->sum('revenue');
        $return_data['data'] = $revenue_list;
        $return_data['total_count'] = $total_count;
        $return_data['total_revenue'] = $total_revenue;
        $return_data['today_revenue'] = $today_revenue;
        $this->success('success', $return_data);
    }
}
